/**
 * TetisDB
 *
 * Classe de busca
 */

package br.com.tetisdb.query;

import br.com.tetisdb.io.snapShot.SnapShotManager;
import br.com.tetisdb.io.snapShot.decoder.Decoder;
import br.com.tetisdb.lang.TetisHashMap;
import br.com.tetisdb.lang.TetisObject;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

public class Finder extends TetisObject {
    //snapshot onde sera efetuada a busca
    private TetisHashMap<String, Object> snapShot;
    //decodificador de objetos que estao no snapshot
    private Decoder decoder;
    
    /**
     * Construtor padrao
     *
     * @param snapShot SnapShot onde a busca sera efetuada.
     */
    public Finder(TetisHashMap<String, Object> snapShot) {
        tetisLogger.debug("Criando Finder");
        this.snapShot = snapShot;
        tetisLogger.debug("Criando Decoder");
        this.decoder = new Decoder(snapShot);
        tetisLogger.debug("Decoder criado");
    }
    
    private void equals(String v1, String v2, TetisHashMap<String, Object> hash, List retorno) {
        if(v1.equals(v2)) {
            retorno.add(hash);
        }
    }
    
    private void diff(String v1, String v2, TetisHashMap<String, Object> hash, List retorno) {
        if(!v1.equals(v2)) {
            retorno.add(hash);
        }
    }
    
    private void greater(String v1, String v2, TetisHashMap<String, Object> hash, List retorno) {
        if(v1.compareToIgnoreCase(v2) >0) {
            retorno.add(hash);
        }
    }
    
    private void greaterequal(String v1, String v2, TetisHashMap<String, Object> hash, List retorno) {
        if(v1.compareToIgnoreCase(v2) >=0) {
            retorno.add(hash);
        }
    }
    
    private void less(String v1, String v2, TetisHashMap<String, Object> hash, List retorno) {
        if(v1.compareToIgnoreCase(v2) <0) {
            retorno.add(hash);
        }
    }
    
    private void lessequal(String v1, String v2, TetisHashMap<String, Object> hash, List retorno) {
        if(v1.compareToIgnoreCase(v2) <=0) {
            retorno.add(hash);
        }
    }
    
    /**
     * Metodo que efetua a busca no snapshot
     *
     * @param query TetisQuery para a busca.
     * @return Retorna uma lista com os objetos encontrados
     */
    protected List find(TQuery query) throws Exception {
        tetisLogger.debug("Efetuando a busca...");
        Class clazz = query.getClazz();
        LinkedList lista = query.getListaAtributos();
        tetisLogger.debug("Resgatando o indice do objeto no SnapShot");
        int indice = ((Integer)((TetisHashMap<String, Object>) snapShot.get(SnapShotManager.INDICE)).get(clazz.getName())).intValue();
        List retorno = new LinkedList();
        List objetos = new ArrayList();
        
        tetisLogger.debug("Listando objetos desse tipo...");
        for(int i=1; i<=indice ; i++) {
            objetos.add(snapShot.get(clazz.getName()+"@"+i));
        }
        
        tetisLogger.debug("Decodificando objetos encontrados...");
        for(Iterator ite = objetos.iterator(); ite.hasNext();) {
            retorno.add(decoder.decode((TetisHashMap<String, Object>) ite.next()));
        }
         /*
          
          
        for(Iterator ite = lista.iterator(); ite.hasNext();) {
            Attribute att = (Attribute) ite;
          
            if(att != null) {
                Object oValue = hash.get(att.getName());
          
                if(oValue != null) {
                    switch (att.getConstrain()) {
                        case EQUALS : equals(att.getValue(), (String) oValue, hash, retorno);
                        case DIFF : diff(att.getValue(), (String) oValue, hash, retorno) ;
                        case GREATER : greater(att.getValue(), (String) oValue, hash, retorno);
                        case GREATER_EQUAL : greaterequal(att.getValue(), (String) oValue, hash, retorno) ;
                        case LESS : less(att.getValue(), (String) oValue, hash, retorno) ;
                        case LESS_EQUAL : lessequal(att.getValue(), (String) oValue, hash, retorno) ;
                    }
                }
            }
        } */
        
        
        return retorno;
    }
}
